//
//  ADSelector.m
//  ADKit
//
//  Created by duzexu on 2018/4/4.
//  Copyright © 2018年 duzexu. All rights reserved.
//

#import "ADSelector.h"
#import "ADKitHeaders.h"

@implementation ADAccessoryView

- (instancetype)initWithSelector:(ADSelector *)selector {
    self = [super initWithFrame:CGRectMake(0, 0, 0, ADSelectorConfig.sharedConfig.accessoryViewHeight)];
    if (self) {
        self.backgroundColor = ADSelectorConfig.sharedConfig.accessoryViewColor;
        [self setBarTintColor:ADSelectorConfig.sharedConfig.accessoryViewColor];
        _titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 180, self.height)];
        [_titleLabel setFont:ADSelectorConfig.sharedConfig.accessoryTitleFont];
        [_titleLabel setTextColor:ADSelectorConfig.sharedConfig.accessoryTitleColor];
        [_titleLabel setTextAlignment:NSTextAlignmentCenter];
        [self addSubview:_titleLabel];
        [_titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
            make.center.equalTo(self);
        }];
#pragma clang diagnostic push
#pragma clang diagnostic ignored"-Wundeclared-selector"
        UIBarButtonItem *leftSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
        leftSpace.width = 16;
        UIButton *cancelBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        [cancelBtn setTitle:ADSelectorConfig.sharedConfig.accessoryCancelTitle forState:UIControlStateNormal];
        [cancelBtn setTitleColor:ADSelectorConfig.sharedConfig.accessoryCancelColor forState:UIControlStateNormal];
        cancelBtn.titleLabel.font = ADSelectorConfig.sharedConfig.accessoryCancelFont;
        [cancelBtn addTarget:selector action:@selector(selectorCancel) forControlEvents:UIControlEventTouchUpInside];
        UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithCustomView:cancelBtn];
        UIBarButtonItem *flexibleSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
        UIButton *doneBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        [doneBtn setTitle:ADSelectorConfig.sharedConfig.accessoryConfirmTitle forState:UIControlStateNormal];
        [doneBtn setTitleColor:ADSelectorConfig.sharedConfig.accessoryConfirmColor forState:UIControlStateNormal];
        doneBtn.titleLabel.font = ADSelectorConfig.sharedConfig.accessoryConfirmFont;
        [doneBtn addTarget:selector action:@selector(selectorDone) forControlEvents:UIControlEventTouchUpInside];
        UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithCustomView:doneBtn];
        UIBarButtonItem *rightSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
        rightSpace.width = 16;
#pragma clang diagnostic pop
        self.items = @[leftSpace, cancelButton, flexibleSpace, doneButton, rightSpace];
        self.translucent = NO;
    }
    return self;
}

@end

@implementation ADSelectorItem

- (BOOL)isEnd {
    return self.subItems.count == 0;
}

- (BOOL)isVaild {
    if (!self.isEnd) {
        return [self.subItems.firstObject isKindOfClass:self.class];
    }
    return YES;
}

+ (nullable NSDictionary<NSString *, id> *)modelContainerPropertyGenericClass {
    return @{@"subItems":[ADSelectorItem class]};
}

@end

@implementation ADSelectorConfig

+ (instancetype)sharedConfig {
    static ADSelectorConfig *config = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        config = [self new];
    });
    return config;
}

- (instancetype)init {
    if (self) {
        _accessoryViewHeight = 44;
        _accessoryViewColor = AD_RGB(247, 247, 247);
        _accessoryCancelTitle = @"取消";
        _accessoryCancelFont = [UIFont systemFontOfSize:14];
        _accessoryCancelColor = AD_RGB(36, 35, 35);
        _accessoryConfirmTitle = @"确认";
        _accessoryConfirmFont = [UIFont boldSystemFontOfSize:14];
        _accessoryConfirmColor = AD_RGB(251, 1, 102);
        _accessoryTitleFont = [UIFont systemFontOfSize:16];
        _accessoryTitleColor = AD_RGB(36, 35, 35);
        _pickerViewHeight = 216;
        _pickerViewRowHeight = 40;
        _pickerRowFont = [UIFont systemFontOfSize:24];;
        _pickerRowColor = AD_RGB(36, 35, 35);
    }
    return self;
}

@end

@interface ADSelector ()<UIPickerViewDataSource,UIPickerViewDelegate> {
    BOOL _isVisible;
    CGFloat _width;
    
    NSInteger _components;
}

@property (nonatomic, strong) UIView *backgroundView;
@property (nonatomic, strong) UIView *selectorView;

@property (nonatomic, strong) UIPickerView *pickerView;
@property (nonatomic, strong) UIDatePicker *datePicker;

@property (nonatomic, strong) NSMutableArray *selectIndexs;
@property (nonatomic, strong) NSDate *selectDate;

@end

@implementation ADSelector

- (instancetype)initWithTitle:(NSString *)title dataSource:(NSArray<ADSelectorItem *> *)datasource selectorType:(ADSelectorType)type {
    self = [super init];
    if (self) {
        if (type == ADSelectorTypeNormal) {
            NSAssert(datasource, @"数据源不能为空");
        }
        _title = [title copy];
        _dataSource = datasource;
        _selectorType = type;
        [self _initSubViews];
        _accessoryView.titleLabel.text = title;
    }
    return self;
}

- (instancetype)init {
    return [self initWithTitle:@"" dataSource:nil selectorType:ADSelectorTypeDate];
}

- (void)showInView:(UIView *)view {
    if (!_isVisible) {
        _width = view.ad_width;
        _backgroundView.frame = view.bounds;
        [view addSubview:_backgroundView];
        _selectorView.frame = CGRectMake(0, view.ad_height, view.ad_width, ADSelectorConfig.sharedConfig.pickerViewHeight+ADSelectorConfig.sharedConfig.accessoryViewHeight);
        _accessoryView.frame = CGRectMake(0, 0, view.ad_width, ADSelectorConfig.sharedConfig.accessoryViewHeight);
        _pickerView.frame = CGRectMake(0, ADSelectorConfig.sharedConfig.accessoryViewHeight, view.ad_width, ADSelectorConfig.sharedConfig.pickerViewHeight);
        _datePicker.frame = CGRectMake(0, ADSelectorConfig.sharedConfig.accessoryViewHeight, view.ad_width, ADSelectorConfig.sharedConfig.pickerViewHeight);
        [self _show];
    }
}

#pragma mark - Getter & Setter
- (void)setTitle:(NSString *)title {
    _title = [title copy];
    _accessoryView.titleLabel.text = title;
}

- (void)setDefaultIndexs:(NSArray *)defaultIndexs {
    _defaultIndexs = defaultIndexs;
    _selectIndexs = defaultIndexs.mutableCopy;
    for (int i = 0; i < _defaultIndexs.count; i++) {
        [_pickerView selectRow:[_defaultIndexs[i] integerValue] inComponent:i animated:NO];
    }
}

- (void)setMinDate:(NSDate *)minDate {
    _minDate = minDate;
    _datePicker.minimumDate = minDate;
}

- (void)setMaxDate:(NSDate *)maxDate {
    _maxDate = maxDate;
    _datePicker.maximumDate = maxDate;
}

- (void)setDefaultDate:(NSDate *)defaultDate {
    _defaultDate = defaultDate;
    _selectDate = defaultDate;
    [_datePicker setDate:_defaultDate animated:NO];
}

#pragma mark - ADAccessoryView
- (void)selectorCancel {
    [self _dismiss];
}

- (void)selectorDone {
    switch (_selectorType) {
        case ADSelectorTypeNormal: {
            NSMutableArray * result = [NSMutableArray array];
            NSArray * list = _dataSource;
            for (NSNumber * index in _selectIndexs) {
                ADSelectorItem * item = [list objectAtIndex:index.integerValue];
                [result addObject:item];
                list = item.subItems;
            }
            _value = result;
        }
            break;
        case ADSelectorTypeDate: {
            _value = _selectDate;
        }
            break;
        default:
            break;
    }
    [self _dismiss];
    if ([_delegate respondsToSelector:@selector(selector:didSelect:)]) {
        [_delegate selector:self didSelect:_value];
    }
}

#pragma mark - Private Method
- (void)_initSubViews {
    _backgroundView = [UIView new];
    _backgroundView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.3];
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(selectorCancel)];
    [_backgroundView addGestureRecognizer:tap];
    _selectorView = [UIView new];
    _selectorView.backgroundColor = UIColor.whiteColor;
    [_backgroundView addSubview:_selectorView];
    _accessoryView = [[ADAccessoryView alloc] initWithSelector:self];
    [_selectorView addSubview:_accessoryView];
    switch (_selectorType) {
        case ADSelectorTypeNormal: {
            _pickerView = [[UIPickerView alloc] initWithFrame:CGRectZero];
            _pickerView.showsSelectionIndicator = YES;
            _pickerView.delegate = self;
            _pickerView.dataSource = self;
            _pickerView.backgroundColor = UIColor.whiteColor;
            [_selectorView addSubview:_pickerView];
            [self _depthOfDataSource:_dataSource depth:1];
            _selectIndexs = [NSMutableArray array];
            for (int i = 0; i < _components; i++) {
                [_selectIndexs addObject:@0];
            }
        }
            break;
        case ADSelectorTypeDate: {
            _datePicker = [[UIDatePicker alloc] initWithFrame:CGRectZero];
            _datePicker.datePickerMode = UIDatePickerModeDate;
            _datePicker.backgroundColor = UIColor.whiteColor;
            [_datePicker addTarget:self action:@selector(datePickerValueChanged:) forControlEvents:UIControlEventValueChanged];
            [_selectorView addSubview:_datePicker];
            _selectDate = _datePicker.date;
        }
            break;
        default:
            break;
    }
}

- (void)_show {
    _isVisible = YES;
    [UIView animateWithDuration:0.3 animations:^{
        self.selectorView.transform = CGAffineTransformMakeTranslation(0, -(ADSelectorConfig.sharedConfig.accessoryViewHeight + ADSelectorConfig.sharedConfig.pickerViewHeight));
    } completion:^(BOOL finished) {
    }];
}

- (void)_dismiss {
    if ([_delegate respondsToSelector:@selector(selectorDidCancel:)]) {
        [_delegate selectorDidCancel:self];
    }
    [UIView animateWithDuration:0.3 animations:^{
        _selectorView.transform = CGAffineTransformMakeTranslation(0, 0);
    } completion:^(BOOL finished) {
        [_backgroundView removeFromSuperview];
        _isVisible = NO;
    }];
}

- (void)_depthOfDataSource:(NSArray<ADSelectorItem *> *)dataSource depth:(NSInteger)depth {
    _components = MAX(depth, _components);
    for (ADSelectorItem *item in dataSource) {
        NSAssert(item.isVaild, @"数据源错误，请检查");
        if (!item.isEnd) {
            [self _depthOfDataSource:item.subItems depth:depth+1];
        }
    }
}

- (NSArray *)_itemsForComponent:(NSInteger)component {
    if (component > 0) {
        NSArray *array = _dataSource;
        for (int i = 0; i < component; i++) {
            ADSelectorItem *item = array[[_selectIndexs[i] integerValue]];
            array = item.subItems;
        }
        return array;
    }else{
        return _dataSource;
    }
}

- (ADSelectorItem *)_itemForComponent:(NSInteger)component forRow:(NSInteger)row {
    if (component > 0) {
        NSArray *array = _dataSource;
        for (int i = 0; i < component; i++) {
            ADSelectorItem *item = array[[_selectIndexs[i] integerValue]];
            array = item.subItems;
        }
        return array[row];
    }else{
        return _dataSource[row];
    }
}

#pragma mark UIPickerViewDelegate & UIPickerViewDataSource
- (NSInteger)numberOfComponentsInPickerView:(nonnull UIPickerView *)pickerView {
    return _components;
}

- (NSInteger)pickerView:(nonnull UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
    return [self _itemsForComponent:component].count;
}

- (NSAttributedString *)pickerView:(UIPickerView *)pickerView attributedTitleForRow:(NSInteger)row forComponent:(NSInteger)component {
    ADSelectorItem *item = [self _itemForComponent:component forRow:row];
    NSAttributedString *string = [[NSAttributedString alloc] initWithString:item.value attributes:@{NSFontAttributeName:ADSelectorConfig.sharedConfig.pickerRowFont,NSForegroundColorAttributeName:ADSelectorConfig.sharedConfig.pickerRowColor}];
    return string;
}

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
    for (int i = 0; i < _selectIndexs.count; i++) {
        if (i == component) {
            [_selectIndexs removeObjectAtIndex:component];
            [_selectIndexs insertObject:[NSNumber numberWithInteger:row] atIndex:component];
        }
        if (i > component) {
            [_selectIndexs removeObjectAtIndex:i];
            [_selectIndexs insertObject:@0 atIndex:i];
            [pickerView reloadComponent:i];
            [pickerView selectRow:0 inComponent:i animated:YES];
        }
    }
}

- (CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component{
    return ADSelectorConfig.sharedConfig.pickerViewRowHeight;
}

#pragma mark - UIDatePicker
- (void)datePickerValueChanged:(UIDatePicker *)picker {
    _selectDate = picker.date;
}

@end
